It is common to have multiple activities simultaneously operating in the
same Lisp process. Furthermore, Lisp programmers tend to expect a
flexible development environment. It must be possible to load and
modify application programs without requiring modifications to other
running programs. CMU Common Lisp achieves this by having a central
scheduling mechanism based on an event-driven, object-oriented paradigm.
An EVENT is some interesting happening that should cause the Lisp
process to wake up and do something. These events include X events and
activity on Unix file descriptors. The object-oriented mechanism is
only available with the first two, and it is optional with X events as
described later in this chapter. In an X event, the window ID is the
object capability and the X event type is the operation code. The Unix
file descriptor input mechanism simply consists of an association list
of a handler to call when input shows up on a particular file
descriptor.
* Menu:
* Object Sets::
* The SERVE-EVENT Function::
* Using SERVE-EVENT with Unix File Descriptors::
* Using SERVE-EVENT with the CLX Interface to X::
* A SERVE-EVENT Example::
File: cmu-user.info Node: Object Sets, Prev: Event Dispatching with SERVE-EVENT, Up: Event Dispatching with SERVE-EVENT, Next: The SERVE-EVENT Function
Object Sets
===========
An object set is a collection of objects that have the same implementation
for each operation. Externally the object is represented by the object
capability and the operation is represented by the operation code. Within
Lisp, the object is represented by an arbitrary Lisp object, and the
implementation for the operation is represented by an arbitrary Lisp function.
The object set mechanism maintains this translation from the external to the
internal representation.
-- Function: make-object-set
NAME &optional DEFAULT-HANDLER
This function makes a new object set. NAME is a string used
only for purposes of identifying the object set when it is printed.
DEFAULT-HANDLER is the function used as a handler when an
undefined operation occurs on an object in the set. You can define
operations with the `serve-'OPERATION functions exported
the `extensions' package for X events
(?). Objects are added with
`system:add-xwindow-object'. Initially the object set has no
objects and no defined operations.
-- Function: object-set-operation
OBJECT-SET OPERATION-CODE
This function returns the handler function that is the
implementation of the operation corresponding to OPERATION-CODE
in OBJECT-SET. When set with `setf', the setter function
establishes the new handler. The `serve-'OPERATION
functions exported from the `extensions' package for X events
(?) call this on behalf of the user when
announcing a new operation for an object set.
-- Function: add-xwindow-object
WINDOW OBJECT OBJECT-SET
These functions add PORT or WINDOW to OBJECT-SET. OBJECT is
an arbitrary Lisp object that is associated with the PORT or WINDOW
capability. WINDOW is a CLX window. When an event occurs,
`system:serve-event' passes OBJECT as an argument to the handler
function.
File: cmu-user.info Node: The SERVE-EVENT Function, Prev: Object Sets, Up: Event Dispatching with SERVE-EVENT, Next: Using SERVE-EVENT with Unix File Descriptors
The SERVE-EVENT Function
========================
The `system:serve-event' function is the standard way for an application
to wait for something to happen. For example, the Lisp system calls
`system:serve-event' when it wants input from X or a terminal stream.
The idea behind `system:serve-event' is that it knows the appropriate
action to take when any interesting event happens. If an application calls
`system:serve-event' when it is idle, then any other applications with
pending events can run. This allows several applications to run "at the
same time" without interference, even though there is only one thread of
control. Note that if an application is waiting for input of any kind,
then other applications will get events.
-- Function: serve-event &optional TIMEOUT
This function waits for an event to happen and then dispatches to the
correct handler function. If specified, TIMEOUT is the number of
seconds to wait before timing out. A time out of zero seconds is legal and
causes `system:serve-event' to poll for any events immediately available
for processing. `system:serve-event' returns true if it serviced at
least one event, and nil otherwise. Depending on the application, when
`system:serve-event' returns true, you might want to call it repeatedly
with a timeout of zero until it returns nil.
If input is available on any designated file descriptor, then this calls the
appropriate handler function supplied by `system:add-fd-handler'.
Since events for many different applications may arrive
simultaneously, an application waiting for a specific event
must loop on `system:serve-event' until the desired event
happens. Since programs such as hemlock call
`system:serve-event' for input, applications usually do
not need to call `system:serve-event' at all; hemlock
allows other application's handlers to run when it goes into an
input wait.
-- Function: serve-all-events &optional TIMEOUT
This function is similar to `system:serve-event', except it serves all
the pending events rather than just one. It returns true if it serviced
at least one event, and nil otherwise.
File: cmu-user.info Node: Using SERVE-EVENT with Unix File Descriptors, Prev: The SERVE-EVENT Function, Up: Event Dispatching with SERVE-EVENT, Next: Using SERVE-EVENT with the CLX Interface to X
Using SERVE-EVENT with Unix File Descriptors
============================================
Object sets are not available for use with file descriptors, as there are
only two operations possible on file descriptors: input and output.
Instead, a handler for either input or output can be registered with
`system:serve-event' for a specific file descriptor. Whenever any input
shows up, or output is possible on this file descriptor, the function
associated with the handler for that descriptor is funcalled with the
descriptor as it's single argument.
-- Function: add-fd-handler fd direction function
This function installs and returns a new handler for the file descriptor
FD. DIRECTION can be either :input if the system should invoke
the handler when input is available or :output if the system should invoke
the handler when output is possible. This returns a unique object representing
the handler, and this is a suitable argument for `system:remove-fd-handler'
FUNCTION must take one argument, the file descriptor.
-- Function: remove-fd-handler HANDLER
This function removes HANDLER, that `add-fd-handler' must have previously
returned.
-- Macro: with-fd-handler
(direction fd function) {FORM}*
This macro executes the supplied forms with a handler installed using FD,
DIRECTION, and FUNCTION. See `system:add-fd-handler'.
-- Function: wait-until-fd-usable
direction fd &optional TIMEOUT
This function waits for up to TIMEOUT seconds for FD to become usable
for DIRECTION (either :input or :output). If TIMEOUT is nil
or unspecified, this waits forever.
-- Function: invalidate-descriptor FD
This function removes all handlers associated with FD. This should only be
used in drastic cases (such as I/O errors, but not necessarily EOF). Normally,
you should use `remove-fd-handler' to remove the specific handler.
File: cmu-user.info Node: Using SERVE-EVENT with the CLX Interface to X, Prev: Using SERVE-EVENT with Unix File Descriptors, Up: Event Dispatching with SERVE-EVENT, Next: A SERVE-EVENT Example
Using SERVE-EVENT with the CLX Interface to X
=============================================
Remember from section *Note Object Sets::, an object set is a collection of
objects, CLX windows in this case, with some set of operations, event keywords,
with corresponding implementations, the same handler functions. Since X allows
multiple display connections from a given process, you can avoid using object
sets if every window in an application or display connection behaves the same.
If a particular X application on a single display connection has windows that
want to handle certain events differently, then using object sets is a
convenient way to organize this since you need some way to map the window/event
combination to the appropriate functionality.
The following is a discussion of functions exported from the `extensions'
package that facilitate handling CLX events through `system:serve-event'.
The first two routines are useful regardless of whether you use
`system:serve-event':
-- Function: open-clx-display
&optional STRING
This function parses STRING for an X display specification
including display and screen numbers. STRING defaults to the
If any field in the display specification is missing, this signals
an error. `ext:open-clx-display' returns the CLX display and
screen.
-- Function: flush-display-events DISPLAY
This function flushes all the events in DISPLAY's event queue
including the current event, in case the user calls this from
within an event handler.
* Menu:
* Without Object Sets::
* With Object Sets::
File: cmu-user.info Node: Without Object Sets, Prev: Using SERVE-EVENT with the CLX Interface to X, Up: Using SERVE-EVENT with the CLX Interface to X, Next: With Object Sets
Without Object Sets
-------------------
Since most applications that use CLX, can avoid the complexity of object
sets, these routines are described in a separate section. The routines
described in the next section that use the object set mechanism are
based on these interfaces.
-- Function: enable-clx-event-handling
DISPLAY HANDLER
This function causes `system:serve-event' to notice when there is input
on DISPLAY's connection to the X11 server. When this happens,
`system:serve-event' invokes HANDLER on DISPLAY in a dynamic
context with an error handler bound that flushes all events from
DISPLAY and returns. By returning, the error handler declines to
handle the error, but it will have cleared all events; thus, entering the
debugger will not result in infinite errors due to streams that wait via
`system:serve-event' for input. Calling this repeatedly on the same
DISPLAY establishes HANDLER as a new handler, replacing any
previous one for DISPLAY.
-- Function: disable-clx-event-handling DISPLAY
This function undoes the effect of `ext:enable-clx-event-handling'.
-- Macro: with-clx-event-handling
(DISPLAY HANDLER) {form}*
This macro evaluates each FORM in a context where
`system:serve-event' invokes HANDLER on DISPLAY whenever there is
input on DISPLAY's connection to the X server. This destroys any